package com.ycy.smartcourseselection.controller;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.ycy.smartcourseselection.common.ResData;
import com.ycy.smartcourseselection.service.LoginService;
import com.ycy.smartcourseselection.vo.login.GetQrCodeRes;
import com.ycy.smartcourseselection.vo.login.ScanQrCodeRes;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.web.bind.annotation.*;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.annotation.Resource;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Api(tags = "微信公众号相关")
@RestController
public class WeiXinController {
    @Resource
    private LoginService loginService;

    @GetMapping("/getQrCode")
    @ApiOperation(value = "获取二维码",notes = "传递参数作为前端认定的二维码唯一标识")
    public ResData<GetQrCodeRes> getQrCode(String qrCodeParams) {
        return loginService.getQrCode(qrCodeParams);
    }

    @GetMapping("/")
    @ApiOperation("响应微信服务器配置请求")
    public String config(@RequestParam(name = "signature") String signature,
                         @RequestParam(name = "timestamp") String timestamp,
                         @RequestParam(name = "nonce") String nonce,
                         @RequestParam(name = "echostr") String echostr) {
        System.out.println(signature);
        System.out.println(timestamp);
        System.out.println(nonce);
        System.out.println(echostr);

        // 验证签名
        String token = "ycy";
        String[] arr = new String[] { token, timestamp, nonce };
        Arrays.sort(arr);
        StringBuilder sb = new StringBuilder();
        for (String s : arr) sb.append(s);
        String encryptedStr = DigestUtils.sha1Hex(sb.toString());
        if (encryptedStr.equals(signature)) return echostr;  //原样返回echostr则视为配置成功
        else return "";
    }

    @PostMapping("/")
    @ApiOperation("响应微信服务器事件推送请求")
    public String handleEvent(@RequestBody String requestBody) throws Exception {
        // 解析XML数据
        Map<String, String> xmlMap = parseXml(requestBody);
        JSONObject xmlData = JSON.parseObject(JSON.toJSONString(xmlMap));
        System.out.println("微信服务器事件推送数据："+xmlData);
        String eventKey = "";
        String event = xmlData.get("Event").toString();
        String timestamp = xmlData.get("CreateTime").toString();
        String userOpenId = xmlData.get("FromUserName").toString();
        if(!"subscribe".equals(event) && !"SCAN".equals(event)) return "success";  //当不为这两个事件时，将直接给微信服务器返回消息，不继续处理

        if("subscribe".equals(event)) eventKey = xmlData.get("EventKey").toString().replace("qrscene_","");  //未关注时扫码
        if("SCAN".equals(event)) eventKey = xmlData.get("EventKey").toString();  //已关注时扫码

        Date date = new Date(Long.parseLong(timestamp) * 1000); // 将时间戳转换为Date对象，需要乘以1000转换为毫秒
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 定义日期时间格式
        String scanTime = sdf.format(date); // 将Date对象格式化为字符串

        ScanQrCodeRes scanQrCodeRes = new ScanQrCodeRes();
        scanQrCodeRes.setOpenId(userOpenId);
        scanQrCodeRes.setScanTime(scanTime);
        scanQrCodeRes.setEventKey(eventKey);

        //给loginService的ScanQrCodeRes对象赋值，返回扫码结果
        loginService.scanQrCodeResponse(scanQrCodeRes);


        // 关注/取关的数据
        // {"CreateTime":"1682525895","EventKey":"","Event":"unsubscribe","ToUserName":"gh_e2d7bd983dbd","FromUserName":"oQOaa5mR8ucfqvaVPUCalX-6F43o","MsgType":"event"}
        // 已关注的用户扫码的数据(EventKey为生成二维码前生成ticket时所携带的参数)
        // {"Ticket":"gQFI8DwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAySXJoZFFoMENlcUMxdVQ5TXhBMVcAAgS3PElkAwQAjScA",
        //         "CreateTime":"1682525612","EventKey":"123","Event":"SCAN",
        //         "ToUserName":"gh_e2d7bd983dbd","FromUserName":"oQOaa5mR8ucfqvaVPUCalX-6F43o",
        //         "MsgType":"event"}
        //未关注时的这两个参数有区别："EventKey":"qrscene_0","Event":"subscribe"

        return "success";  //给微信服务器返回消息，证实该服务器已接收数据。
    }

    //解析XML数据的方法
    private Map<String, String> parseXml(String xml) throws Exception {
        HashMap<String, String> map = new HashMap<>();
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        InputStream is = new ByteArrayInputStream(xml.getBytes("UTF-8"));
        Document document = builder.parse(is);
        Element root = document.getDocumentElement();
        NodeList nodeList = root.getChildNodes();
        for (int i = 0; i < nodeList.getLength(); i++) {
            Node node = nodeList.item(i);
            if (node.getNodeType() == Node.ELEMENT_NODE) {
                map.put(node.getNodeName(), node.getTextContent());
            }
        }
        return map;
    }
}
